#include <iostream>
#include <signal.h>
#include <cassert>
#include <unistd.h>
#include <cstdlib>
#include <cstring>

using namespace std;

void showPending(const sigset_t &pending){
    cout << "pid : " << getpid() << "\t";
    cout << "pending : ";
    for (int signo = 1; signo <= 31; signo++)
    {
        if(sigismember(&pending,signo)){
            cout << "1";
        }else{
            cout << "0";
        }
    }
    cout << endl;

}

void handler(int signo){
    cout << "收到 " << signo << "信号，执行捕捉动作" << endl;
    int cnt = 0;
    while(cnt++<10){
        sleep(2);
        cout << "进度：" << cnt << "0%" << endl;
        sigset_t pending;
        sigemptyset(&pending);
        sigpending(&pending);
        showPending(pending);
        
    }
    cout << "处理完毕" << endl;
}

int main(){

    // //1、屏蔽2号信号
    // sigset_t set, oset;
    // //1.1、初始化
    // sigemptyset(&set);
    // sigemptyset(&oset);
    // //1.2、将2号信号添加到set中
    // sigaddset(&set, SIGINT);
    // //1.3、将信号屏蔽字设置到进程中
    // //默认block表为空
    // sigprocmask(SIG_BLOCK, &set,&oset);

    // //2、循环打印pending表
    // //2.3.2、自定义信号动作
    // signal(SIGINT, handler);
    // int cnt = 0;
    // while (1)
    // {
    //     //2.1、获取pending表
    //     sigset_t pending;
    //     int n = sigpending(&pending);
    //     assert(n == 0);

    //     //2.2、打印pending表
    //     showPending(pending);
    //     sleep(1);

    //     //2.3.1、恢复对所有信号的屏蔽
    //     if(cnt == 5){
    //         cout << "解除屏蔽！" << endl;
    //         sigprocmask(SIG_SETMASK, &oset, &set);
    //     }
    //     cnt++;
    // }

    struct sigaction act, oact;
    memset(&act, 0, sizeof(act));
    memset(&oact, 0, sizeof(oact));
    act.sa_handler = handler;
    act.sa_flags = 0;
    sigemptyset(&act.sa_mask);

    //已经知道在处理2号信号的时候会阻塞其他的2号信号 -- 在block表中把2号信号对应的位置置为1
    //现在想要把和2号信号动作相似的其他信号也阻塞

    sigaddset(&act.sa_mask, 3);
    sigaddset(&act.sa_mask, 4);
    sigaddset(&act.sa_mask, 5);


    sigaction(2, &act, &oact);

    while(1){
        cout << "pid : " << getpid() << endl;
        sleep(1);
    }

    return 0;
}